import pandas as pd            #基于numpy的库，可做数据分析
import re                      #提供正则表达式功能，帮助检查一个字符串是否与某种模式匹配
import jieba                   #中文分词库
from sklearn.feature_extraction.text import TfidfVectorizer  #TfidfVectorizer类可以将文本转换为数值型特征向量


#train=pd.read_csv('train.news.csv')         #读取训练集数据  
train=pd.read_csv('train1.csv')   
x=train.drop('label',axis=1)                #去掉标签列数据，把剩下的放到x里。 axis=1表示按列删
y=train['label']                            #把标签列数据单独放到y里

#test=pd.read_csv('test.feature.csv')     #读取测试集数据
test=pd.read_csv('test.csv')
test_id=test['id']                       #测试集的id列数据放到test_id中

messages=x.copy()                        #把去掉标签列的训练集数据复制给messages
messages2=test.copy()                    #把测试集数据复制给messages2


#文本处理
def tokenize(messages):                  #分词
    tokenized_titles=[]                  #创建一个新的空列表盛放分词后的标题们
    for i in range(0,len(messages)): 
        
        review=re.sub('[^\u4e00-\u9fa5]+',' ', messages['content'][i])  #\u4e00-\u9fa5表示unicode中的中文字符编码，匹配Title中不是中文字符的字符，把它们换成空格                                                         

        words=jieba.cut(review)                      #调用jieba中文分词库进行分词
        tokenized_title = ' '.join(words)            #分好的词中间加上空格
        tokenized_titles.append(tokenized_title)     #把所有分好词的标题连起来
    return tokenized_titles


#import string
# stopwords = ['是', '的', '了', '在', '和', '有', '更', '与', '对于', '并', '我', '他', '她', '它', '我们', '他们', '她们', '它们']
# def remove_stopwords_punctuation_digits(titles):#去停用词、标点符号和数字
#     processed_titles=[]
#     for i in range(0,len(titles)):
#         title = titles[i].translate(str.maketrans('', '', string.punctuation + string.digits))#建立转换表，让所有数字和标点在转换表中对应空字符，然后对标题进行转换，相当于去除数字和标点
#         processed_words=[word for word in titles[i] if word not in stopwords]
#         processed_titles.append(' '.join(processed_words))
#     return processed_titles  #效果没有提升



#预处理数据集
tokenized_titles=tokenize(messages)           #调用函数完成训练集和测试集的分词操作
tokenized_titles2=tokenize(messages2)


 #特征提取 格式转化 
vectorizer = TfidfVectorizer()                                  #创建一个TfidfVectorizer的实例
features = vectorizer.fit_transform(tokenized_titles).toarray() #将分词好的训练集标题转换为数值型特征向量，fit_transform用于首次拟合模型并获取特征，适用训练集
features2 = vectorizer.transform(tokenized_titles2).toarray()   #将分词好的测试集标题转换为数值型特征向量，transform用于将之前已经拟合的特征模型应用于其他数据集，适用测试集

X_train=features                                                #上一步转换好的特征向量就是用来训练的标题
X_test=features2                                                #用来测试的标题
Y_train=y                                                       #用来训练的label数据       
                                        

from sklearn.linear_model import PassiveAggressiveClassifier
model=PassiveAggressiveClassifier(max_iter=50000)                #被动攻击分类模型，max_iter是训练数据的最大传递次数，准确率78.02%
#被动攻击分类模型在预测结果与真实结果一致时不改变模型参数，在不一致时被动触发攻击性，对模型参数进行更改，减小损失函数，数据集反复迭代多次，最小化损失，提高正确率

# from sklearn.linear_model import LinearRegression  
# model = LinearRegression()                                       #线性回归模型，低于75.66％，找到特征与目标变量（真正label值之间）的关系，根据最小二乘法拟合出线性直线，纵坐标即为预测label，这样使得真实和预测差别最小

# from sklearn.tree import DecisionTreeClassifier  
# model = DecisionTreeClassifier()                                 #决策树模型，正确率76.18％ ，每个内部节点表示一个特征属性上的测试，每个分支代表测试的结果，每个叶节点代表一种分类结果。

# from sklearn.linear_model import RidgeClassifier
# model=RidgeClassifier(alpha=1.0)                                   #Ridge回归模型，低于75.66％，通过调节 alpha 参数可以控制正则化的强度，较大的 alpha 值会增加正则化的影响，从而降低模型的复杂度，有助于减少过拟合的风险。相反，较小的 alpha 值会减少正则化的影响，使模型更复杂，有可能增加过拟合的风险。


# model = LogisticRegression(random_state=42)                        #逻辑回归模型 准确率低于78.02%，参数 random_state=42 表示设置了随机数种子，作为随机数生成器的起始值，每次得到确定的随机数序列，用于控制模型的随机性，使得模型的训练结果可以复现。

# from sklearn import svm  
# model = svm.SVC(kernel='linear')                                   #svm模型，准确率低于75.66%，kernel='linear'是线性核函数，可以在原始空间中分类

# from sklearn.ensemble import RandomForestClassifier  
# model = RandomForestClassifier()                                   #随机森林模型，准确率小于78.02％，随机采样，随机选择特征，构建多个决策树，对分类结果投票或取平均

# from sklearn.naive_bayes import MultinomialNB
# model = MultinomialNB()                                            #朴素贝叶斯模型，准确率67.67％，贝叶斯算法，算每个类别先验概率，特征在该类别下出现的条件概率，得到后验概率，取后验概率最高的类别



model.fit(X_train, Y_train)                                          #训练模型

Y_pred = model.predict(X_test)                                       #根据测试数据获得预测的结果



# 将id和预测结果输出为DataFrame变成csv文件

output = pd.DataFrame({'id':test_id , 'label': Y_pred}) #将id和预测结果转化为DataFrame对象
output.to_csv('outcome.csv', index=False)               #把最终结果写到csv文件中，index=False表示不把DataFrame索引index写入文件

# AUC=78.02%
